home *** CD-ROM | disk | FTP | other *** search
- /*
- *=============================================================================
- * tSippLight.c
- *-----------------------------------------------------------------------------
- * Tcl commands to manage SIPP light sources.
- *-----------------------------------------------------------------------------
- * Copyright 1992 Mark Diekhans
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies. Mark Diekhans makes
- * no representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *-----------------------------------------------------------------------------
- * $Id: tSippLight.c,v 2.0 1992/11/02 03:56:21 markd Rel $
- *=============================================================================
- */
-
- #include "tSippInt.h"
-
- /*
- * Constants indicating light types.
- */
- #define TSIPP_LIGHTSOURCE 1
- #define TSIPP_SPOTLIGHT 2
-
- /*
- * Internal function prototypes.
- */
- static void
- BindLightToHandle _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- Lightsource *lightPtr));
-
- static Lightsource *
- LightHandleToPtr _ANSI_ARGS_((tSippGlob_pt tSippGlobPtr,
- char *handle,
- unsigned validTypes));
-
- /*=============================================================================
- * BindLightToHandle --
- * Bind a lightsource to a handle, setting up the table entry.
- *
- * Parameters:
- * o tSippGlobPtr (I) - Pointer to the Tcl SIPP globals. The handle is
- * returned in interp->result.
- * o lightPtr (I) - A pointer to the light source.
- *-----------------------------------------------------------------------------
- */
- static void
- BindLightToHandle (tSippGlobPtr, lightPtr)
- tSippGlob_pt tSippGlobPtr;
- Lightsource *lightPtr;
- {
- Lightsource **lightEntryPtr;
-
- lightEntryPtr = (Lightsource **)
- Tcl_HandleAlloc (tSippGlobPtr->lightTblPtr,
- tSippGlobPtr->interp->result);
- *lightEntryPtr = lightPtr;
- }
-
- /*=============================================================================
- * LightHandleToPtr --
- * Utility procedure to convert a light handle to a light pointer.
- * Parameters:
- * o tSippGlobPtr (I) - A pointer to the Tcl SIPP global structure.
- * o handle (I) - A light handle.
- * o validTypes (I) - Indicates the type of light this operation is valid
- * for. These are bit flags, more than one may be or-ed together:
- * o TSIPP_LIGHTSOURCE - If the operation is valid for lightsources.
- * o TSIPP_SPOTLIGHT - If the lightsource is valid for spotlights.
- * Returns:
- * A pointer to the lightsource or spot light, or NULL if an error occured.
- *-----------------------------------------------------------------------------
- */
- static Lightsource *
- LightHandleToPtr (tSippGlobPtr, handle, validTypes)
- tSippGlob_pt tSippGlobPtr;
- char *handle;
- unsigned validTypes;
- {
- Lightsource **lightEntryPtr;
-
- lightEntryPtr = (Lightsource **)
- Tcl_HandleXlate (tSippGlobPtr->interp,
- tSippGlobPtr->lightTblPtr, handle);
- if (lightEntryPtr == NULL)
- return NULL;
-
- switch ((*lightEntryPtr)->type) {
- case LIGHT_DIRECTION:
- case LIGHT_POINT:
- if (!(TSIPP_LIGHTSOURCE & validTypes)) {
- Tcl_AppendResult (tSippGlobPtr->interp,
- "operation not valid on lightsources",
- (char *) NULL);
- return NULL;
- }
- break;
- case SPOT_SHARP:
- case SPOT_SOFT:
- if (!(TSIPP_SPOTLIGHT & validTypes)) {
- Tcl_AppendResult (tSippGlobPtr->interp,
- "operation not valid on spotlights",
- (char *) NULL);
- return NULL;
- }
- break;
- };
- return *lightEntryPtr;
-
- } /* LightHandleToPtr */
-
- /*=============================================================================
- * SippLightSourceCreate --
- * Implements the command:
- * SippLightSourceCreate {x y z} color type
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippLightSourceCreate (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Vector vector;
- Color intensity;
- int type;
- Lightsource *lightPtr;
-
- if (argc != 4) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " {x y z} color type", (char *) NULL);
- return TCL_ERROR;
- }
- if (!TSippConvertVertex (tSippGlobPtr, argv [1], &vector))
- return TCL_ERROR;
- if (!TSippConvertColor (tSippGlobPtr, argv [2], &intensity))
- return TCL_ERROR;
- if (STREQU (argv [3], "DIRECTION"))
- type = LIGHT_DIRECTION;
- else if (STREQU (argv [3], "POINT"))
- type = LIGHT_POINT;
- else {
- Tcl_AppendResult (interp, "expected one of \"DIRECTION\" or ",
- "\"POINT\", got \"", argv [3], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = lightsource_create (vector.x, vector.y, vector.z,
- intensity.red, intensity.grn, intensity.blu,
- type);
- BindLightToHandle (tSippGlobPtr, lightPtr);
- return TCL_OK;
-
- } /* SippLightSourceCreate */
-
- /*=============================================================================
- * SippSpotLightCreate --
- * Implements the command:
- * SippSpotLightCreate position point opening color type shadow
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSpotLightCreate (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Vector position, point;
- double opening;
- Color color;
- int type, shadow;
- Lightsource *lightPtr;
-
- if (argc != 7) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " position point opening color type shadow",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (!TSippConvertVertex (tSippGlobPtr, argv [1], &position))
- return TCL_ERROR;
- if (!TSippConvertVertex (tSippGlobPtr, argv [2], &point))
- return TCL_ERROR;
- if (!TSippConvertAngleDeg (tSippGlobPtr, argv [3], &opening))
- return TCL_ERROR;
- if (!TSippConvertColor (tSippGlobPtr, argv [4], &color))
- return TCL_ERROR;
- if (STREQU (argv [5], "SHARP"))
- type = SPOT_SHARP;
- else if (STREQU (argv [5], "SOFT"))
- type = SPOT_SOFT;
- else {
- Tcl_AppendResult (interp, "expected one of \"SHARP\" or ",
- "\"SOFT\", got \"", argv [5], "\"", (char *) NULL);
- return TCL_ERROR;
- }
- if (Tcl_GetBoolean (interp, argv [6], &shadow) != TCL_OK)
- return TCL_ERROR;
-
- lightPtr = spotlight_create (position.x, position.y, position.z,
- point.x, point.y, point.z,
- opening,
- color.red, color.grn, color.blu,
- type, shadow);
-
- BindLightToHandle (tSippGlobPtr, lightPtr);
- return TCL_OK;
-
- } /* SippSpotLightCreate */
-
- /*=============================================================================
- * SippLightDestruct --
- * Implements the command:
- * SippLightDestruct lightlist
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippLightDestruct (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- handleList_t lightList;
- handleList_t lightEntryList;
- int idx;
-
- if (argc != 2) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0], " lightlist",
- (char *) NULL);
- return TCL_ERROR;
- }
- if (!TSippHandleListConvert (tSippGlobPtr, tSippGlobPtr->lightTblPtr,
- argv [1], &lightList, &lightEntryList))
- return TCL_ERROR;
-
- for (idx = 0; idx < lightList.len; idx++) {
- light_destruct ((Lightsource *) lightList.ptr [idx]);
- Tcl_HandleFree (tSippGlobPtr->lightTblPtr, lightEntryList.ptr [idx]);
- }
-
- TSippHandleListFree (&lightList);
- TSippHandleListFree (&lightEntryList);
- return TCL_OK;
-
- } /* SippLightDestruct */
-
- /*=============================================================================
- * SippLightSourcePut --
- * Implements the command:
- * SippLightSourcePut light {x y z}
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippLightSourcePut (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- Vector point;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light {x y z}", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_LIGHTSOURCE);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (!TSippConvertVertex (tSippGlobPtr, argv [2], &point))
- return TCL_ERROR;
-
- lightsource_put (lightPtr, point.x, point.y, point.z);
- return TCL_OK;
-
- } /* SippLightSourcePut */
-
- /*=============================================================================
- * SippSpotLightPos --
- * Implements the command:
- * SippSpotLightPos light {x y z}
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSpotLightPos (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- Vector point;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light {x y z}", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_SPOTLIGHT);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (!TSippConvertVertex (tSippGlobPtr, argv [2], &point))
- return TCL_ERROR;
-
- spotlight_pos (lightPtr, point.x, point.y, point.z);
- return TCL_OK;
-
- } /* SippSpotLightPos */
-
- /*=============================================================================
- * SippSpotLightOpening --
- * Implements the command:
- * SippSpotLightOpening light opening
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSpotLightOpening (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- double opening;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light opening", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_SPOTLIGHT);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (!TSippConvertAngleDeg (tSippGlobPtr, argv [2], &opening))
- return TCL_ERROR;
-
- spotlight_opening (lightPtr, opening);
- return TCL_OK;
-
- } /* SippSpotLightOpening */
-
- /*=============================================================================
- * SippSpotLightShadows --
- * Implements the command:
- * SippSpotLightShadows light flag
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippSpotLightShadows (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- int flag;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light flag", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_SPOTLIGHT);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (Tcl_GetBoolean (interp, argv [2], &flag) != TCL_OK)
- return TCL_ERROR;
-
- spotlight_shadows (lightPtr, flag);
- return TCL_OK;
-
- } /* SippSpotLightShadows */
-
- /*=============================================================================
- * SippLightColor --
- * Implements the command:
- * SippLightColor light color
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippLightColor (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- Color color;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light color", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_LIGHTSOURCE | TSIPP_SPOTLIGHT);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (!TSippConvertColor (tSippGlobPtr, argv [2], &color))
- return TCL_ERROR;
-
- light_color (lightPtr, color.red, color.blu, color.grn);
- return TCL_OK;
-
- } /* SippLightColor */
-
- /*=============================================================================
- * SippLightActive --
- * Implements the command:
- * SippLightActive light flag
- * Note:
- * This procedure has standard Tcl command calling sematics. ClientData
- * contains a pointer to the Tcl SIPP global structure.
- *-----------------------------------------------------------------------------
- */
- static int
- SippLightActive (clientData, interp, argc, argv)
- char *clientData;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- tSippGlob_pt tSippGlobPtr = (tSippGlob_pt) clientData;
- Lightsource *lightPtr;
- int flag;
-
- if (argc != 3) {
- Tcl_AppendResult (interp, "wrong # args: ", argv [0],
- " light flag", (char *) NULL);
- return TCL_ERROR;
- }
- lightPtr = LightHandleToPtr (tSippGlobPtr, argv [1],
- TSIPP_LIGHTSOURCE | TSIPP_SPOTLIGHT);
- if (lightPtr == NULL)
- return TCL_ERROR;
- if (Tcl_GetBoolean (interp, argv [2], &flag) != TCL_OK)
- return TCL_ERROR;
-
- light_active (lightPtr, flag);
- return TCL_OK;
-
- } /* SippLightActive */
-
- /*=============================================================================
- * TSippLightInit --
- * Initialized the light source commands.
- *
- * Parameters:
- * o tclSippGlobP (I) - Pointer to the top level global data structure.
- * (currently unused).
- *-----------------------------------------------------------------------------
- */
- void
- TSippLightInit (tSippGlobPtr)
- tSippGlob_pt tSippGlobPtr;
- {
- static tSippTclCmdTbl_t cmdTable [] = {
- {"SippLightSourceCreate", SippLightSourceCreate},
- {"SippSpotLightCreate", SippSpotLightCreate},
- {"SippLightDestruct", SippLightDestruct},
- {"SippLightSourcePut", SippLightSourcePut},
- {"SippSpotLightPos", SippSpotLightPos},
- {"SippSpotLightOpening", SippSpotLightOpening},
- {"SippSpotLightShadows", SippSpotLightShadows},
- {"SippLightColor", SippLightColor},
- {"SippLightActive", SippLightActive},
- {NULL, NULL}
- };
-
- tSippGlobPtr->lightTblPtr =
- Tcl_HandleTblInit ("light", sizeof (Lightsource *), 4);
-
- TSippInitCmds (tSippGlobPtr, cmdTable);
-
- } /* TSippLightInit */
-